﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Web;
using System.Web.Mvc;
using System.Linq.Expressions;
using System.Dynamic;
using System.Reflection;
using System.Text;
using System.IO;



namespace RFinance.Infrastructure
{
    public class JqGridParser<T> where T: class 
    {
        public dynamic ObterJsonGrid(IQueryable<T> query)
        {
            Func<IQueryable<T>, dynamic> get = (q) =>
                                                   {
                                                       var items = q.ToList();
                                                       Type tipo = items.GetType().GetGenericArguments()[0];
                                                       PropertyInfo[] myPropertyInfo = tipo.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                                                       List<IDictionary<string,object>> row = new List<IDictionary<string, object>>();
                                                       //definindo qual propriedade que vai ser o id
                                                       var id = (from p in myPropertyInfo
                                                                 where p.Name.Contains("Id")
                                                                 select p.Name).FirstOrDefault();
                                                       foreach (var item in items)
                                                       {
                                                           //preenchendo as propriedades dos items
                                                           var r = new ExpandoObject();
                                                           ((IDictionary<string, object>)r).Add("id", item.GetType().GetProperty(id).GetValue(item, null));
                                                           //pegando as outras propriedades diferentes do id
                                                           var propertiesLeft = from p in myPropertyInfo
                                                                                where p.Name != id
                                                                                select p;
                                                           var cell = new List<string>();
                                                           foreach(var info in propertiesLeft)
                                                           {
                                                               cell.Add(info.GetValue(item, null) == null ? "" : info.GetValue(item, null).ToString());
                                                           }
                                                           ((IDictionary<string, object>)r).Add("cell", cell);
                                                           row.Add(r.ToDictionary(x => x.Key, x=>x.Value));
                                                       }
                                                       return row;
                                                   };


            var totalPages = Math.Ceiling((double)query.Count() / 50);
            var result = new
                             {
                                 total = Convert.ToInt32(totalPages),
                                 page = 1,
                                 records = query.Count(),
                                 rows =  get(query) 
                             };
            return result;
        }

        private dynamic ObterDynamic(IQueryable<T> query)
        {
            var items = query.ToList();
            Type tipo = items.GetType().GetGenericArguments()[0];
            PropertyInfo[] myPropertyInfo = tipo.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            dynamic exp = new ExpandoObject();
            //pegando a primeira propriedade Id, caso nao encontre pega a primeira encontrada
            var id = (from p in myPropertyInfo
                     where p.Name.Contains("Id")
                     select p.Name).FirstOrDefault();
            if (id == null)
            {
                id = myPropertyInfo.First().Name;
            }
            ((IDictionary<string, object>)exp).Add("id", id);
            var restante = from r in myPropertyInfo
                           where r.Name != id
                           select r;

            List<Object> columns = new List<object>();
            foreach (var propertyInfo in restante)
            {
                columns.Add(propertyInfo.Name);
            }

            ((IDictionary<string, object>)exp).Add("cell", columns);
            var obj = exp as IDictionary<string, object>;
            obj = obj.ToDictionary(x => x.Key, x => x.Value);
            return obj;
        }
    }
}